import {
  atom,
  selector,
  selectorFamily,
  waitForAll,
  waitForNone,
} from "recoil";

const tableOfUsers = {
  1: { id: 1, name: "Kelvin", friends: [2, 3] },
  2: { id: 2, name: "John", friends: [3, 1] },
  3: { id: 3, name: "Marrey", friends: [4, 2] },
  4: { id: 4, name: "Susan", friends: [5, 2] },
  5: { id: 5, name: "Nikco", friends: [4, 1, 2] },
};

async function fetchUser({ userId }) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(tableOfUsers[userId]);
    }, 2000);
  });
}

export const currentUserIdState = atom({
  key: "CurrentUserId",
  default: 1,
});

export const userInfoQuery = selectorFamily({
  key: "UserInfoQuery",
  get: (userId) => async () => {
    const response = await fetchUser({ userId });
    return response;
  },
});

export const currentUserInfoQuery = selector({
  key: "CurrentUserInfoQuery",
  get: ({ get }) => get(userInfoQuery(get(currentUserIdState))),
});

export const friendsInfoQuery = selector({
  key: "FriendsInfoQuery",
  get: ({ get }) => {
    const { friends } = get(currentUserInfoQuery);

    // waitForAll
    // const friendList = get(
    //   waitForAll(friends.map((friendId) => userInfoQuery(friendId)))
    // );
    // return friendList;

    // waitForNone
    const friendLoadables = get(
      waitForNone(friends.map((friendId) => userInfoQuery(friendId)))
    );
    return friendLoadables
      .filter(({ state }) => state === "hasValue")
      .map(({ contents }) => contents);
  },
});
